home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / s342q07.lha / syszm.c < prev    next >
C/C++ Source or Header  |  1995-09-12  |  16KB  |  653 lines

  1. /*
  2.  * *       syszm.c * * External protocol handlers.
  3.  */
  4. /*
  5.  * *       history * * 89Aug14 HAW  Rewritten for versatility. * 88Nov13 HAW
  6.  * Created.
  7.  */
  8. #define SYSTEM_DEPENDENT
  9. #include "ctdl.h"
  10. #include "dos.h"
  11.  
  12. int       Jsystem(char *);
  13. long      Do_Zmodem(char *files, int direction);
  14.                          /** returns TRUE if error **/
  15. /**
  16.    Contents
  17.  AddExternProtocolOptions() to system menus
  18.  AddNames()         Allows building strings of names
  19.  AddOurOpts()       add  options to a menu list.
  20.  DoesNumerous()     BATCH checking function.
  21.  EatExtMessage()    Send a bundle of messages
  22.  EatProtocol()      Eats a protocol definition line.
  23.  ExternalProtocol() Handles all external protocols
  24.  FindProtocolCode() finds a protocol value for id purposes
  25.  FindProtoName()    returns the name of the ext protocol.
  26.  FindProtocol()     work function for finding things.
  27.  InitProtocols()   initializes external protocols
  28. **/
  29. char      MakeCmdLine(char *, char *, char *miscdata, int len);
  30. void      AddName(DirEntry *);
  31. int       ExternalProtocol(int, char, char *, char *, char);
  32. typedef struct
  33.   {
  34.     char      Selector,
  35.              *Name,
  36.               Down,
  37.              *CmdLine,
  38.              *Display,
  39.               Many;
  40.     int       ProtVal;
  41.  
  42.   }
  43. PROTOCOL;
  44. char      GetSizes = FALSE;
  45. int       ExCount = 4;
  46. void     *EatProtocol(char *line);
  47. void     *FindProtocol(PROTOCOL *, int *);
  48. void      InitProtocols(void);
  49. static SListBase ExtProtocols =
  50. {
  51.   NULL, FindProtocol, NULL, NULL, EatProtocol
  52.  
  53. };
  54. static char FindCode = FALSE;
  55. extern CONFIG cfg;
  56. extern MessageBuffer msgBuf;
  57. extern aRoom roomBuf;
  58. extern char loggedIn;
  59. extern int SystemPort;
  60. extern char onConsole;              /*
  61.  
  62.                                              * Where we get stuff from
  63.                                              */
  64. extern logBuffer logBuf;
  65. char      AddStringToMCL(char *target, char *source, int len);
  66. void      EnglishWork(char *target, char Ups);
  67. char      cmdline[125];             /* we have a limit  */
  68. /*
  69.  * * InitProtocols() * * This function initializes external protocols.
  70.  */
  71. void
  72. InitProtocols()
  73. {
  74.   SYS_FILE  fn;
  75.  
  76.   makeSysName(fn, "ctdlprot.sys", &cfg.roomArea);
  77.   MakeList(&ExtProtocols, fn, NULL);
  78.  
  79. }
  80. /**
  81.   EatProtocol()
  82. This function eats a protocol line.
  83.   Format:
  84.  [selector] [1/M] [name] [u/d] [command line]
  85.  [selector] [I]   [name] [u/d] [Internal Zmodem]
  86. **/
  87. void     *
  88. EatProtocol(char *line)
  89. {
  90.   PROTOCOL *temp;
  91.   char     *c,
  92.            *err;
  93.  
  94.   if (cfg.BoolFlags.debug)
  95.     splitF(NULL, "External:%s\n", line);
  96.   err = line;
  97.   NormStr(line);
  98.   if (strLen(line) == 0)
  99.     return NULL;
  100.   temp = GetDynamic(sizeof *temp);
  101.   temp->Selector = line[0];
  102.   line += 2;
  103.   temp->Many = toUpper(line[0]);
  104.   /**
  105.      Could be "1" or "M"
  106.   **/
  107.   switch (temp->Many)
  108.     {
  109.         case '1':       /*
  110.                          * Single file, external protocol handler
  111.                          */
  112.         case 'M':       /*
  113.                          * Multiple files, external protocol handler
  114.                          */
  115.         case 'I':       /*
  116.                          * Internal Zmodem
  117.                         */
  118.           break;
  119.         default:
  120.           splitF(NULL, "Invalid Protocol in CTDLPROT.SYS\n%s\n", err);
  121.  
  122.     }
  123.   line += 2;
  124.   if ((c = strchr(line, ' ')) != NULL)
  125.     *c = 0;
  126.   temp->Name = strdup(line);
  127.   line = lbyte(line) + 1;
  128.   temp->Down = (toUpper(line[0]) == 'D') ? TRUE : FALSE;
  129.   line += 2;
  130.   temp->CmdLine = strdup(line);
  131.   temp->ProtVal = ExCount++;
  132.   sPrintf(cmdline, "%s%c\b%s", NTERM, temp->Selector, temp->Name);
  133.   temp->Display = strdup(cmdline);
  134.   return temp;
  135.  
  136. }
  137. /**
  138.  ExternalProtocol()
  139.   This function handles external protocols.  It
  140.   also checks for external message uploads/downloads.
  141. **/
  142. int
  143. ExternalProtocol(int protocol, char upload, char *mask, char *phrase,
  144.                      char Move)
  145. {
  146.   PROTOCOL *Prot;
  147.   int       toReturn;
  148.   extern long byteRate;
  149.   extern int SystemPort;
  150.   long realCount;
  151.   SpecialMessage("Status:External Protocol");
  152.   if (cfg.BoolFlags.debug)
  153.     {
  154.         splitF(NULL, "ExternalProtocol(%d,%s,%s,%s,%s)\n", protocol,
  155.         (upload ? "TRUE" : "FALSE"), mask, phrase, (Move ? "TRUE" : "FALSE"));
  156.  
  157.     };
  158.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  159.     {
  160.         if (cfg.BoolFlags.debug) splitF(NULL, "SearchList failed to find Protocol\n");
  161.         return TRAN_FAILURE;
  162.  
  163.     };
  164.   if (Move && !setSpace(&roomBuf))
  165.     {
  166.         if (cfg.BoolFlags.debug)   splitF(NULL, "SetSpace Failed\n");
  167.         return TRAN_FAILURE;
  168.  
  169.     };
  170.   if (!upload)
  171.     {
  172.         msgBuf.mbtext[0] = 0;
  173.         wildCard(AddName, mask, FALSE, phrase, TRUE);
  174.  
  175.     }
  176.   else
  177.     strCpy(msgBuf.mbtext, mask);
  178.   if (Prot->Many == '1' || Prot->Many == 'M')   /*
  179.                                                                  * old style
  180.                                                                  */
  181.     {
  182.         if (cfg.BoolFlags.debug) splitF(NULL, "Making external command line\n");
  183.         if (!MakeCmdLine(cmdline, Prot->CmdLine, msgBuf.mbtext, sizeof cmdline - 1))
  184.           {
  185.             if (strchr(mask, '>') != NULL || strchr(mask, '<') != NULL)
  186.                 {
  187.                   if (cfg.BoolFlags.debug) splitF(NULL, "List too long\n");
  188.                   Output_Citadel_Message("FILLTL", NULL, NULL, NULL);
  189.                   if (Move)     homeSpace();
  190.                   return TRAN_FAILURE;
  191.  
  192.                 }
  193.             else if (!MakeCmdLine(cmdline, Prot->CmdLine, mask, sizeof cmdline - 1))
  194.                 {
  195.                   if (cfg.BoolFlags.debug) splitF(NULL, "List too long\n");
  196.                   Output_Citadel_Message("FILLTL", NULL, NULL, NULL);
  197.                   if (Move)  homeSpace();
  198.                   return TRAN_FAILURE;
  199.  
  200.                 }
  201.  
  202.           };
  203.  
  204.     };
  205.   if (!upload)
  206.     fileMessage(FL_START, mask, TRUE, protocol, 0l);
  207.   if (loggedIn)
  208.     printf("\n(%s)\n %s", logBuf.lbname, cmdline);
  209.   if (Prot->Many == '1' || Prot->Many == 'M')   /* old style */
  210.     {
  211.         Jsystem(cmdline);
  212.  
  213.     }
  214.   else
  215.  
  216. /**
  217.    Internal Zmodem
  218.  
  219. **/
  220.     {
  221.  
  222.     if( Do_Zmodem(msgBuf.mbtext, upload) )
  223.        return TRAN_FAILURE ;
  224.  
  225.  
  226.     };
  227.   if (!upload)
  228.     {
  229.         GetSizes = TRUE;
  230.         ExCount = 0;
  231.         strCpy(msgBuf.mbtext, "   ");
  232.         realCount = wildCard(AddName, mask, Move, phrase, TRUE);
  233.         GetSizes = FALSE;
  234.         if (Move)         homeSpace();
  235.         fileMessage(FL_EX_END, mask, TRUE, protocol, 0l         /*
  236.                                                                                  * filled in
  237.                                                                                  */ );
  238.         toReturn = TRAN_SUCCESS;
  239.   /* if( realCount > 0 )transRecDown(mask, realCount); */
  240.  
  241.     }
  242.   else
  243.     {
  244.         toReturn = ((strcmp(mask, "msg") == 0) || (access(mask, 0) == 0))
  245.           ? TRAN_SUCCESS : TRAN_FAILURE;
  246.  
  247.     }
  248.   return toReturn;
  249.  
  250. }
  251. UNS_16    intrates[] =
  252. {
  253.   30, 120, 240, 480, 960, 1440, 1920, 3840, 5760
  254.  
  255. };
  256.  
  257. /*
  258.  * * MakeCmdLine() * * This function creates a command line, including
  259.  * supported substitution * parameters.  This should be detailed in this
  260.  * comment but isn't.
  261.  */
  262. char
  263. MakeCmdLine(char *target, char *source, char *miscdata, int len)
  264. {
  265.   extern int thisLog;               /*
  266.  
  267.                                              * entry currently in logBuf
  268.                                              */
  269.   char     *c,
  270.            *temp,
  271.             NoOverflow = TRUE;
  272.   int       i;
  273.  
  274.   for (i = 0, c = source; *c; c++)
  275.     {
  276.         if (i > len - 2)
  277.           {
  278.             NoOverflow = FALSE;
  279.             break;
  280.  
  281.           }
  282.         if (*c == '%')
  283.           {
  284.             target[i] = 0;
  285.             c++;
  286.             switch (*c)
  287.                 {
  288.                   case 'a':     /* baud rate */
  289.                     if (onConsole)
  290.                         sPrintf(lbyte(target), "%d", 0);
  291.                     else
  292.                         sPrintf(lbyte(target), "%ld",
  293.                                   (cfg.DepData.LockPort != -1) ?
  294.                             (long)(intrates[cfg.DepData.LockPort] * 10) : byteRate * 10);
  295.                     break;
  296.                   case 'b':     /* bps */
  297.                     sPrintf(lbyte(target), "%ld",
  298.                                 (cfg.DepData.LockPort != -1) ?
  299.                                 (long)(intrates[cfg.DepData.LockPort]) : byteRate);
  300.                     break;
  301.                   case 'c':     /* port # */
  302.                     sPrintf(lbyte(target), "%d", SystemPort);
  303.                     break;
  304.                   case 'e':     /* log number of the user */
  305.                     sPrintf(lbyte(target), "%d", thisLog);
  306.                     break;
  307.                   case 'f':     /* ANSI code of the user  */
  308.                     sPrintf(lbyte(target), "0");
  309.                     break;
  310.                   case 'g':     /* file mask */
  311.                     NoOverflow = AddStringToMCL(target, miscdata, len);
  312.                     break;
  313.                   case 'h':
  314.                     if (byteRate != 0)
  315.                         sPrintf(lbyte(target), "COM%d", SystemPort);
  316.                     else
  317.                         strCat(target, "LOCAL");
  318.                     break;
  319.                   case 'i':
  320.                     NoOverflow = AddStringToMCL(target, roomBuf.rbname, len);
  321.                     break;
  322.                   case 'j':
  323.                     if ((temp = FindDirName(roomBuf.rbArea)) != NULL)
  324.                         NoOverflow = AddStringToMCL(target, temp, len);
  325.                     break;
  326.                   case 'k':
  327.                     sPrintf(lbyte(target), "%d", logBuf.lbwidth);
  328.                     break;
  329.                   case 'd':
  330.                     strCat(target, logBuf.lbname);
  331.                     break;
  332.  
  333.                 }
  334.             while (target[i])
  335.                 i++;
  336.  
  337.           }
  338.         else
  339.           target[i++] = *c;
  340.  
  341.     }
  342.   target[i] = 0;
  343.   if (cfg.BoolFlags.debug)
  344.     splitF(NULL, "Command Line is %d long\n", strlen(target));
  345.   return NoOverflow;
  346.  
  347. }
  348. /*
  349.  * * AddStringToMCL() * * This adds a string as needed, I guess.
  350.  */
  351. char
  352. AddStringToMCL(char *target, char *source, int len)
  353. {
  354.   if (strlen(source) + strlen(target) < len - 2)
  355.     {
  356.         strCat(target, source);
  357.         return TRUE;
  358.  
  359.     }
  360.   else
  361.     {
  362.         strncpy(lbyte(target), source, len - strlen(target) - 1);
  363.         target[len - 1] = 0;
  364.         return FALSE;
  365.  
  366.     }
  367.  
  368. }
  369. static char **TheOpts,
  370.           IsUpload;
  371.  
  372. /*
  373.  * * AddExternProtocolOptions() * * This function adds external protocol
  374.  * options to system menus.
  375.  */
  376. void
  377. AddExternProtocolOptions(char **Opts, char upload)
  378. {
  379.   void      AddOurOpts();
  380.  
  381.   TheOpts = Opts;
  382.   IsUpload = upload;
  383.   RunList(&ExtProtocols, AddOurOpts);
  384.  
  385. }
  386. /*
  387.  * * AddOurOpts() * * This function does the actual work of adding an option
  388.  * to a menu list.
  389.  */
  390. void
  391. AddOurOpts(PROTOCOL * d)
  392. {
  393.   if ((d->Down && IsUpload) ||
  394.         (!d->Down && !IsUpload))
  395.     return;
  396.   ExtraOption(TheOpts, d->Display);
  397.  
  398. }
  399. /*
  400.  * * FindProtocolCode() * * This function finds a protocol value for id
  401.  * purposes.
  402.  */
  403. int
  404. FindProtocolCode(int c, char upload)
  405. {
  406.   PROTOCOL *Prot;
  407.  
  408.   FindCode = TRUE;
  409.   IsUpload = upload;
  410.   if (isalpha(c))
  411.     c = toUpper(c);
  412.   Prot = SearchList(&ExtProtocols, &c);
  413.   FindCode = FALSE;
  414.   if (Prot == NULL)
  415.     return -1;
  416.   return Prot->ProtVal;
  417.  
  418. }
  419. /*
  420.  * * FindProtoName() * * This function returns the name of the external
  421.  * protocol.
  422.  */
  423. char     *
  424. FindProtoName(int protocol)
  425. {
  426.   PROTOCOL *Prot;
  427.  
  428.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  429.     return NULL;
  430.   return Prot->Name;
  431.  
  432. }
  433. /*
  434.  * * FindProtocol() * * This work function helps find a protocol in a list.
  435.  */
  436. void     *
  437. FindProtocol(PROTOCOL * d, int *val)
  438. {
  439.   if (FindCode)
  440.     {
  441.         if (*val == d->Selector && IsUpload != d->Down)
  442.           return d;
  443.  
  444.     }
  445.   else if (*val == d->ProtVal)
  446.     return d;
  447.   return NULL;
  448.  
  449. }
  450. /*
  451.  * * DoesNumerous() * * Does this protocol support BATCH downloads?
  452.  */
  453. char
  454. DoesNumerous(int protocol)
  455. {
  456.   PROTOCOL *Prot;
  457.  
  458.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  459.     return FALSE;
  460.   return (char) (Prot->Many == 'M' || Prot->Many == 'I');
  461.  
  462. }
  463. /*
  464.  * * EatExtMessage() * * This function eat a message upload using an
  465.  * external protocol.  It returns * TRAN_SUCCESS on success, TRAN_FAILURE
  466.  * otherwise.
  467.  */
  468. int
  469. EatExtMessage(int protocol)
  470. {
  471.   struct FileInfoBlock *info;
  472.   int       result;
  473.   extern char TDirBuffer[];
  474.   char      dir[80];
  475.  
  476.   MakeTempDir();
  477.   if ((result = ExternalProtocol(protocol, TRUE, "msg", "", FALSE)) == TRAN_SUCCESS)
  478.     {
  479.         chdir(TDirBuffer);
  480.         info = (struct FileInfoBlock *) calloc(1, sizeof(struct FileInfoBlock));
  481.  
  482.         if (info == NULL)
  483.           {
  484.             splitF(NULL, "Unable to get memory for info buffer(syszm)\n");
  485.  
  486.           }
  487.         else
  488.           {
  489.             result = dfind(info, ALL_FILES, 0); /*
  490.                                                                  * get the filename
  491.                                                                  */
  492.             if (result == 0)
  493.                 {
  494.                   if (cfg.BoolFlags.debug)
  495.                     splitF(NULL, "Ingesting:", info->fib_FileName);
  496.                   ingestFile(info->fib_FileName, &msgBuf);
  497.                   unlink(info->fib_FileName);
  498.  
  499.                 }
  500.             else
  501.                 splitF(NULL, "No file found!(syszm)\n");
  502.             free(info);
  503.  
  504.           };
  505.  
  506.     }
  507.   else
  508.     {
  509.         splitF(NULL, "Transfer failed(syszm)\n");
  510.         if (cfg.BoolFlags.debug)
  511.           {
  512.             (void) getcd(0, dir);
  513.             splitF(NULL, " Dir:%s\n Other:%s\n", dir, TDirBuffer);
  514.  
  515.           };
  516.  
  517.     };
  518.   homeSpace();
  519.   rmdir(TDirBuffer);
  520.   return result;
  521.  
  522. }
  523. /*
  524.  * * AddName() * * This function is used in conjunction with wildCard to
  525.  * generate a list * of names, optionally with filesizes in parenthesis
  526.  * 4/line.  This is used * to generate a command line or a report in
  527.  * FILELOG.SYS.
  528.  */
  529. void
  530. AddName(DirEntry * file)
  531. {
  532.   if (strLen(msgBuf.mbtext) > MAXTEXT - 200)
  533.     {
  534.         if (GetSizes)
  535.           strCat(msgBuf.mbtext, ".");
  536.  
  537.     }
  538.   else
  539.     {
  540.         sPrintf(lbyte(msgBuf.mbtext), " %s", file->unambig);
  541.         if (GetSizes)
  542.           {
  543.             sPrintf(lbyte(msgBuf.mbtext), " (%ld)", file->FileSize);
  544.             if (++ExCount == 4)
  545.                 {
  546.                   strCat(msgBuf.mbtext, "\n   ");
  547.                   ExCount = 0;
  548.  
  549.                 }
  550.  
  551.           }
  552.  
  553.     }
  554.  
  555. }
  556. static char *msgText,
  557.           UpsOnly;
  558.  
  559. /*
  560.  * * UpProtsEnglish() * * This generates a list of upload protocol names.
  561.  * It is used by the help * system.
  562.  */
  563. void
  564. UpProtsEnglish(char *target)
  565. {
  566.   EnglishWork(target, TRUE);
  567.  
  568. }
  569. /*
  570.  * * DownProtsEnglish() * * This function generates a list of download
  571.  * protocol names for use by the * help system.
  572.  */
  573. void
  574. DownProtsEnglish(char *target)
  575. {
  576.   EnglishWork(target, FALSE);
  577.  
  578. }
  579. /*
  580.  * * EnglishWork() * * This function does the real work of generating names.
  581.  */
  582. void      List_Names(PROTOCOL *);
  583. void
  584. EnglishWork(char *target, char Ups)
  585. {
  586.   char     *c;
  587.  
  588.   target[0] = 0;
  589.   msgText = target;
  590.   UpsOnly = Ups;
  591.   RunList(&ExtProtocols, List_Names);
  592.   if ((c = strrchr(target, ',')) == NULL)
  593.     strCpy(target, "None.");
  594.   else
  595.     strCpy(c, ".");
  596.  
  597. }
  598. /*
  599.  * * List_Names() * * This function helps build the list of protocols
  600.  * available.
  601.  */
  602. void
  603. List_Names(PROTOCOL * d)
  604. {
  605.   char     *c;
  606.  
  607.   if (UpsOnly != d->Down)
  608.     {
  609.         c = lbyte(msgText);
  610.         sPrintf(c, "<%c>%s, ", d->Selector, (d->Selector == d->Name[0]) ?
  611.                   d->Name + 1 : d->Name);
  612.  
  613.     }
  614.  
  615. }
  616. /*
  617.  * * ExternalTransfer() * * This function is used by the network for
  618.  * external protocol transfers.
  619.  */
  620. char
  621. ExternalTransfer(int protocol, char *filename)
  622. {
  623.   PROTOCOL *Prot;
  624.   char     *name,
  625.            *fn;
  626.  
  627.   if ((Prot = SearchList(&ExtProtocols, &protocol)) == NULL)
  628.     return FALSE;
  629.   fn = strdup(filename);
  630.   if ((name = strrchr(fn, '\\')) != NULL)
  631.     {
  632.         *name++ = 0;
  633.         chdir(fn);
  634.  
  635.     }
  636.   else
  637.     {
  638.         name = fn;
  639.  
  640.     }
  641.   if (!MakeCmdLine(cmdline, Prot->CmdLine, name, sizeof cmdline - 1))
  642.     {
  643.         free(fn);
  644.         return FALSE;
  645.  
  646.     }
  647.   Jsystem(cmdline);
  648.   free(fn);
  649.   homeSpace();
  650.   return TRUE;
  651.  
  652. }
  653.